一、Blade 基本
- Blade 為 Larvel 提供的模板引擎(語言)
- 雙大括號表示 echo 輸出內容
- Blade 自訂標籤可以控制模板的結構、繼承、自定義的 Blade 語法等, e.g. @if、@else、@foreach...
- Blade 會被編譯成 PHP 程式碼放入快取, 也可以在其中使用一般 PHP 語法, 但不建議因為不屬於 Blade 的內容應當在外部處理
# Blade 基本 echo 值, 以 php 變數方式設定值
<h1> {{ $title }} </h1> /* 相對於 <?php echo htmlentities($title); ?> */
# echo 未轉譯的內容, 不使用 htmlentities()
<h1> {{!! $title !!}} </h1>
# 在前面添加 @ 告知 Blade 不用解析, 提供給其他模板引擎替換 e.g. Vue
@{{ $otherValue }}
# 使用 @verbatim 可以定義一個區塊 Blade 不轉義
@verbatim
<h1> {{ title }} </h1>
@endverbatim
二、控制結構
條件邏輯
- @if
- 「@if (條件)」 會被編譯成 PHP 程式碼 「」, 其他 @else, @elseif 與 @endif 也會
@if ( $products->count > 1 )
商品數量: {{ $product->count }}
@else
目前沒有相關類別商品
@endif
- @unless
@unless ( $product->count )
商品數量: {{ $product->count }}
@endunless
迴圈
- 有 @for、@foreach、@while, 運作方式與 PHP 中一樣
- @for
@for ($i = 0; $i < $products->count; $i++)
索引: {{ $i }}
@endfor
- @foreach
@foreach ( $products as $product )
商品名稱: {{ $product->name }}
@endforeach
- @while
@while ( $product = array_pop($products) )
商品名稱: {{ $product->name }}
@endwhile
- @forelse
# 提供使用者當迴圈為空的時候執行另一段代碼
@forelse ( $products as $product )
商品名稱: {{ $product->name }}
@empty
目前沒有相關商品
@endforelse
- @foreach 與 @forelse 內的 $loop 變數 (Laravel 5.3)
- 在這兩個 Blade 指令內會有 $loop 變數( php stdClass 物件 ), 能夠取得迴圈的狀態、父迴圈的內容
<ul>
@foreach ( $products as $product )
<li>商品索引: {{ $loop->index }} </li> <!-- 取的物件的索引, 值從0開始 -->
<li>第 {{ $loop->iteration }} 個商品</li> <!-- 取的目前索引, 值從1開始 -->
<li>還剩下多少商品: {{ $loop->remaining }}</li> <!-- 取回迴圈目前還剩下多少商品 -->
<li>商品總數量: {{ $loop->count }}</li> <!-- 取回回圈內有多少商品 -->
<li>
<!-- 判斷項目是否為第一筆資料 -->
這是第一個商品嗎? {{ $loop->first ? '是' : '否' }}
</li>
<li>
<!-- 判斷項目是否為最後一筆資料 -->
這是最後一個商品嗎? {{ $loop->last ? '是' : '否' }}
</li>
<li>
<!-- 判斷迴圈有幾層 -->
迴圈總共有: {{ $loop->depth }} 層
</li>
@if ( count($product->comments) > 0 )
<li>
<ul>
@foreach ( $product->comments as $comment )
<!-- 取回復階層的項目 -->
<li> 這是第 {{ $loop->parent->iteration }} 商品的留言</li>
@endforeach
</ul>
</li>
@endif
@endforeach
</ul>
模板繼承
- Blade 提供模板可以繼承結構, 設定區域與變數在父子模板中傳遞資料內容, 以便擴展整個 view
- 主要指令 @section/@show/@endsction, @yield 定義區域
<!-- A. 父模板 master.blad.php -->
<html>
<head>
<!-- 第一個參數是要接收的變數名稱, 第二個參數是預設出現的文字 -->
<title> @yield('title', 'XXX 購物網站') </title>
</head>
<body>
<div class="container-fluid">
<!-- 網站內容 -->
@yield('content')
</div>
<!-- 引入網站需要的 javascript -->
<!-- 在父模板中定義 @section 要以 @show結尾 -->
<!-- 子模板中可以透過 @parent 來取的父模板 @section 中的內容 -->
@section('JSscript')
<script src="./js/app.js"></script>
@show
</body>
</html>
<!-- B. 子模板 productList.blade.php -->
<!-- 繼承 resources/views/layout/master.blade.php 模板 -->
@extends('layout.master')
<!-- 傳變數值 title 給父模板 -->
@section('title', '商品列表')
<!-- 傳變數值 content 給父模板, 在子模板中 @section 要用 @endsection 結尾 -->
@section('content')
商品介紹內容
@endsection
<!-- 利用 @parent 取得父模板內容, 並添加新的 js 連結 -->
@section('JSscript')
@parent
<script scr="./js/product.js"></script>
@endsection
- @include
- 可以單獨引入 view 模板, 像是加數購物車按鈕、登入按鈕
- 其他相關語法 @includeIf、 @includeWhen、 @includeFirst, 添加條件判斷
<div>
<p>您尚未登入, 請在 [登入/註冊] 後繼續以下動作</p>
<!-- 第一個參數為模板位置, 第二個參數為要傳遞的變數(關聯式陣列) -->
@include('components.signin_btn', ['text' => '登入'])
@include('components.signup_btn', ['text' => '註冊'])
</div>
- @each
- 當需要迴圈遍歷陣列時可以使用, 每次會 @include 項目的模板, 像是在側邊欄引入商品分類
<div class="sideBar">
<ul>
<!--
參數1: 要使用模板名稱
參數2: 要遍歷的陣列
參數3: 模板讀取的變數名稱
參數4(可選): 當陣列為空時,要顯示的模板
-->
@each('product.categoryLi', $product_categroy, 'category', 'product.emptyCatrgory')
</ul>
</div>
使用堆疊
- 在建立模板時, 個頁面有時需要自己的 CSS 或 Javascript, 此時可以使用 @stack, @push, @perpend Blade 指令來動態新增樣式與 js
<!-- master.blade.php -->
<html>
<head>
<title>Master Blade</title>
</head>
<body>
<script src="./js/app.js"></script>
<!-- 建立一個區域提供子模板動態添加 js -->
@stack('scripts')
</body>
</html>
<!-- first_sub.blade.php -->
@extend('layout.master')
<!-- 將 js 檔案引入, 放置到 @stack 最後一行 -->
@push('scripts')
<script type="./assest/js/first_sub.js"></script>
@endpush
<!-- secondary_sub.blade.php -->
@extend('layout.first_sub')
<!-- 將 js 檔案引入, 放置到 @stack 第一行 -->
@perpend
<script type="./assest/js/secondary_sub.js"></script>
@endperpend
<!--
最終 js 引入順序
<script src="./js/app.js"></script>
<script type="./assest/js/secondary_sub.js"></script>
<script type="./assest/js/first_sub.js"></script>
-->